/***************************************************
FileName: shutil.c
Purpose: Provide additional necessary utilities for the main processing shell
commands
Description: Contains additional necessary functions necessary to creating
a working shell from the executable.
Modified by Grant Meyers
***************************************************/
#include "shell.h"
#include "parser.h"
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <unistd.h>
#include <pwd.h>
#include <fcntl.h>
#include <limits.h>
#include <signal.h>
#include <sys/types.h>
#include <sys/resource.h>
#include <sys/wait.h>

void stripcrlf(char *temp) {
	while (temp[0] &&
	        ((temp[strlen(temp)-1] == 13) || (temp[strlen(temp)-1] == 10))) {
		temp[strlen(temp)-1] = 0;
	}
}

char *gethomedir(void) {
	static char homedir[_POSIX_PATH_MAX * 2]; /* Just to be safe. */
	struct passwd *pws;

	pws = getpwuid(getuid());
	if (!pws) {
		if(fprintf(stderr, "getpwuid() on %d failed", (int) getuid())<0) {
			perror("Error: fprintf printed negative number of characters.  shutil line 37");
		}
		exit(255);
	}

	strcpy(homedir, pws->pw_dir);
	return homedir;
}

char *getuserhomedir(char *user) {
	static char homedir[_POSIX_PATH_MAX * 2]; /* Just to be safe. */
	struct passwd *pws;

	pws = getpwnam(user);
	if (!pws) {
		fprintf(stderr, "getpwnam() on %s failed", user);
		exit(255);
	}

	strcpy(homedir, pws->pw_dir);
	return homedir;
}

void signal_c_init(void) {
	struct sigaction act;

	//Error Checking 6
	if( sigemptyset(&act.sa_mask) == -1) {
		perror("Error: sigemptyset failed.  shutil.c line 65");
		exit(EXIT_FAILURE);
	}
	//
	act.sa_flags = SA_RESTART;

	act.sa_handler = (void *)waitchildren;
	//Error Checking 7
	if(sigaction(SIGCHLD, &act, NULL) == -1) {
		perror("Error: sigaction failed.  shutil.c line 77");
		exit(EXIT_FAILURE);
	}
	
	act.sa_handler = (void *)keylog_exit;
	if(sigaction(SIGQUIT, &act, NULL) == -1) {
		perror("Error: sigaction failed.  shutil.c line 80");
		exit(EXIT_FAILURE);
	}
	if(sigaction(SIGINT, &act, NULL) == -1) {
		perror("Error: sigaction failed.  shutil.c line 84");
		exit(EXIT_FAILURE);
	}
}

void waitchildren(int signum) {
	//No real way to check for error.  Once wait3 is done waiting for child it returns error code...
	while (wait3((int *)NULL, WNOHANG, (struct rusage *)NULL) > 0) {}
}

/* Check to see whether or not we should run in background */

int checkbackground(char *cmdline) {
	/* First, strip off any trailing spaces (this has not yet been run
	   through strtok) */

	striptrailingchar(cmdline, ' ');

	/* We are looking for an ampersand at the end of the command. */

	if (cmdline[strlen(cmdline)-1] == '&') {
		cmdline[strlen(cmdline)-1] = 0; /* Remove the ampersand from the command */
		return 1;            /* Indicate that this is background mode */
	}
	return 0;
}

void striptrailingchar(char *temp, char tc) {
	while (temp[0] && (temp[strlen(temp)-1] == tc)) {
		temp[strlen(temp)-1] = 0;
	}
}
